package com.jewaton.auth.commons.util;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.NotReadablePropertyException;
import org.springframework.util.Assert;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * 类属性拷贝工具类
 * 
 */
public class BeanUtil {

	/**
	 * Copy <b>the not null property</b> values of the given source bean into
	 * the given target bean.
	 * <p>
	 * Note: The source and target classes do not have to match or even be
	 * derived from each other, as long as the properties match. Any bean
	 * properties that the source bean exposes but the target bean does not will
	 * silently be ignored. 数字类型的属性 如果不需拷贝 注意加入ignoreProperties
	 * 
	 * @param source
	 *            the source bean
	 * @param target
	 *            the target bean
	 * @param ignoreProperties
	 *            array of property names to ignore
	 * @throws BeansException
	 *             if the copying failed
	 */
	public static void copyNotNullProperties(Object source, Object target,
			String[] ignoreProperties) throws BeansException {
		copyProperties(source, target, null, ignoreProperties);
	}

	private static void copyProperties(Object source, Object target,
			Class<?> editable, String[] ignoreProperties) throws BeansException {

		Assert.notNull(source, "Source must not be null");
		Assert.notNull(target, "Target must not be null");

		Class<?> actualEditable = target.getClass();
		if (editable != null) {
			if (!editable.isInstance(target)) {
				throw new IllegalArgumentException("Target class ["
						+ target.getClass().getName()
						+ "] not assignable to Editable class ["
						+ editable.getName() + "]");
			}
			actualEditable = editable;
		}
		PropertyDescriptor[] targetPds = BeanUtils
				.getPropertyDescriptors(actualEditable);
		List<String> ignoreList = (ignoreProperties != null) ? Arrays
				.asList(ignoreProperties) : null;

		for (PropertyDescriptor targetPd : targetPds) {
			if (targetPd.getWriteMethod() != null
					&& (ignoreProperties == null || (!ignoreList
							.contains(targetPd.getName())))) {
				PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(
						source.getClass(), targetPd.getName());
				if (sourcePd != null && sourcePd.getReadMethod() != null) {
					try {
						Method readMethod = sourcePd.getReadMethod();
						if (!Modifier.isPublic(readMethod.getDeclaringClass()
								.getModifiers())) {
							readMethod.setAccessible(true);
						}
						Object value = readMethod.invoke(source);
						// 忽略null值 、空字符串 && Number缺省为0 注意ignore
						if (value == null
								|| StringUtil.isBlank(value.toString())) {
							continue;
						}
						Method writeMethod = targetPd.getWriteMethod();
						if (!Modifier.isPublic(writeMethod.getDeclaringClass()
								.getModifiers())) {
							writeMethod.setAccessible(true);
						}
						writeMethod.invoke(target, value);
					} catch (Throwable ex) {
						throw new FatalBeanException(
								"Could not copy properties from source to target",
								ex);
					}
				}
			}
		}
	}
	
	public static void copyPropertiesKong(Object source, Object target,
			Class<?> editable, String[] ignoreProperties) throws BeansException {

		Assert.notNull(source, "Source must not be null");
		Assert.notNull(target, "Target must not be null");

		Class<?> actualEditable = target.getClass();
		if (editable != null) {
			if (!editable.isInstance(target)) {
				throw new IllegalArgumentException("Target class ["
						+ target.getClass().getName()
						+ "] not assignable to Editable class ["
						+ editable.getName() + "]");
			}
			actualEditable = editable;
		}
		PropertyDescriptor[] targetPds = BeanUtils
				.getPropertyDescriptors(actualEditable);
		List<String> ignoreList = (ignoreProperties != null) ? Arrays
				.asList(ignoreProperties) : null;

		for (PropertyDescriptor targetPd : targetPds) {
			if (targetPd.getWriteMethod() != null
					&& (ignoreProperties == null || (!ignoreList
							.contains(targetPd.getName())))) {
				PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(
						source.getClass(), targetPd.getName());
				if (sourcePd != null && sourcePd.getReadMethod() != null) {
					try {
						Method readMethod = sourcePd.getReadMethod();
						if (!Modifier.isPublic(readMethod.getDeclaringClass()
								.getModifiers())) {
							readMethod.setAccessible(true);
						}
						Object value = readMethod.invoke(source);
						// 忽略null值 、空字符串 && Number缺省为0 注意ignore
						if (value == null
								|| StringUtil.isBlankKong(value.toString())) {
							continue;
						}
						Method writeMethod = targetPd.getWriteMethod();
						if (!Modifier.isPublic(writeMethod.getDeclaringClass()
								.getModifiers())) {
							writeMethod.setAccessible(true);
						}
						writeMethod.invoke(target, value);
					} catch (Throwable ex) {
						throw new FatalBeanException(
								"Could not copy properties from source to target",
								ex);
					}
				}
			}
		}
	}

	/**
	 * 复制Bean 指定属性值到另一个Bean对应的属性
	 * 
	 * @param source
	 * @param target
	 * @param properties
	 *            要复制值的属性名称
	 * @throws BeansException
	 */
	public static void copyProperties(Object source, Object target,
			String[] properties) throws BeansException {

		Assert.notNull(source, "Source must not be null");
		Assert.notNull(target, "Target must not be null");

		Class<?> actualEditable = target.getClass();
		PropertyDescriptor[] targetPds = BeanUtils
				.getPropertyDescriptors(actualEditable);
		List<String> propertiesList = (properties != null) ? Arrays
				.asList(properties) : null;

		for (PropertyDescriptor targetPd : targetPds) {
			if (targetPd.getWriteMethod() != null
					&& (properties == null || (propertiesList.contains(targetPd
							.getName())))) {
				PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(
						source.getClass(), targetPd.getName());
				if (sourcePd != null && sourcePd.getReadMethod() != null) {
					try {
						Method readMethod = sourcePd.getReadMethod();
						if (!Modifier.isPublic(readMethod.getDeclaringClass()
								.getModifiers())) {
							readMethod.setAccessible(true);
						}
						Object value = readMethod.invoke(source);
						// 忽略null值 、空字符串 && Number缺省为0 注意ignore
						if (value == null
								|| StringUtil.isBlank(value.toString())) {
							continue;
						}
						Method writeMethod = targetPd.getWriteMethod();
						if (!Modifier.isPublic(writeMethod.getDeclaringClass()
								.getModifiers())) {
							writeMethod.setAccessible(true);
						}
						writeMethod.invoke(target, value);
					} catch (Throwable ex) {
						throw new FatalBeanException(
								"Could not copy properties from source to target",
								ex);
					}
				}
			}
		}
	}

	/**
	 * 检查对象的属性是否为null或空字符串，不支持原生态类型long,int,boolean等 因为原始类型没有值会返回缺省值0，不属于null
	 * 
	 * @param clazz
	 *            对象所属类
	 * @param obj
	 *            对象
	 * @param ignoreProperties
	 *            忽略列表
	 * @return 要检查的属性有一个为空就返回false
	 * @throws BeansException
	 */
	public static boolean checkPropertiesWithIgnore(Class<?> clazz, Object obj,
			String[] ignoreProperties) throws BeansException {
		if (obj == null || !clazz.isAssignableFrom(obj.getClass())) {
			return false;
		}
		Class<?> actualEditable = obj.getClass();
		PropertyDescriptor[] targetPds = BeanUtils
				.getPropertyDescriptors(actualEditable);
		List<String> ignoreList = (ignoreProperties != null) ? Arrays
				.asList(ignoreProperties) : null;
		for (PropertyDescriptor targetPd : targetPds) {
			Method readMethod = targetPd.getReadMethod();
			if (readMethod != null
					&& (ignoreList == null || !ignoreList.contains(targetPd
							.getName()))) {
				try {
					Object value = readMethod.invoke(obj);
					if (value == null || StringUtil.isBlank(value.toString()))
						return false;
				} catch (Throwable ex) {
					throw new FatalBeanException(
							"Could not read properties from obj", ex);
				}
			}
		}
		return true;
	}

	/**
	 * 检查对象的属性是否为null或空字符串，不支持原生态类型long,int,boolean等 因为原始类型没有值会返回缺省值0，不属于null
	 * 
	 * @param clazz
	 *            对象所属类
	 * @param obj
	 *            对象
	 * @param checkProperties
	 *            检查列表
	 * @return 要检查的属性有一个为空就返回false
	 * @throws BeansException
	 */
	public static boolean checkProperties(Class<?> clazz, Object obj,
			String[] checkProperties) throws BeansException {
		if (obj == null || !clazz.isAssignableFrom(obj.getClass())) {
			return false;
		}
		Class<?> actualEditable = obj.getClass();
		PropertyDescriptor[] targetPds = BeanUtils
				.getPropertyDescriptors(actualEditable);
		List<String> checkList = (checkProperties != null) ? Arrays
				.asList(checkProperties) : null;
		for (PropertyDescriptor targetPd : targetPds) {
			Method readMethod = targetPd.getReadMethod();
			if (readMethod != null && checkList.contains(targetPd.getName())) {
				try {
					Object value = readMethod.invoke(obj);
					if (value == null || StringUtil.isBlank(value.toString()))
						return false;
				} catch (Throwable ex) {
					throw new FatalBeanException(
							"Could not read properties from obj", ex);
				}
			}
		}
		return true;
	}

	/**
	 * 获取对象属性值，支持嵌套属性（like el表达式）
	 * 
	 * @param obj
	 * @param property
	 *            p1.p2
	 * @return
	 */
	public static Object getProperty(Object obj, String property) {
		if (obj == null || StringUtil.isBlank(property))
			return null;
		String[] propertyArray = property.split("\\.");
		Object value = null;
		int methodCount = 0;
		Class<?> actualEditable = obj.getClass();
		PropertyDescriptor[] targetPds = BeanUtils
				.getPropertyDescriptors(actualEditable);
		for (PropertyDescriptor targetPd : targetPds) {
			Method readMethod = targetPd.getReadMethod();
			if (readMethod != null
					&& targetPd.getName().equals(propertyArray[0])) {
				try {
					value = readMethod.invoke(obj);
					methodCount++;
					if (propertyArray.length > 1 && value != null) {
						value = getProperty(value, propertyArray[1]);
					}
					break;
				} catch (Throwable ex) {
					throw new FatalBeanException(
							"Could not read properties from obj", ex);
				}
			}
		}
		if (methodCount == 0) {
			throw new NotReadablePropertyException(actualEditable,
					propertyArray[0]);
		}
		return value;
	}

	/**
	 * 比较两个对象中的指定属性值是否相同，不同则返回true
	 * 
	 * @param source
	 * @param target
	 * @param properties
	 *            要比较的属性名
	 * @return
	 * @throws BeansException
	 */
	public static boolean compareProperties(Object source, Object target,
			String[] properties) throws BeansException {
		boolean result = true;

		Assert.notNull(source, "Source must not be null");
		Assert.notNull(target, "Target must not be null");
		Class<?> actualEditable = target.getClass();
		PropertyDescriptor[] targetPds = BeanUtils
				.getPropertyDescriptors(actualEditable);
		List<String> ignoreList = (properties != null) ? Arrays
				.asList(properties) : null;
		for (PropertyDescriptor targetPd : targetPds) {
			if (targetPd.getWriteMethod() != null
					&& (properties == null || (ignoreList.contains(targetPd
							.getName())))) {
				PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(
						source.getClass(), targetPd.getName());
				if (sourcePd != null && sourcePd.getReadMethod() != null) {
					try {
						Method readMethod = sourcePd.getReadMethod();
						if (!Modifier.isPublic(readMethod.getDeclaringClass()
								.getModifiers())) {
							readMethod.setAccessible(true);
						}
						Object value = readMethod.invoke(source);
						Method readMethod2 = targetPd.getReadMethod();
						if (!Modifier.isPublic(readMethod2.getDeclaringClass()
								.getModifiers())) {
							readMethod2.setAccessible(true);
						}
						Object value2 = readMethod2.invoke(target);

						if (value == null && value2 == null) {
							return result;
						} else if (value != null && value2 != null) {
							if (value.equals(value2)) {
								return result;
							} else {
								result = false;
								return result;
							}
						} else {
							result = false;
							return result;
						}
					} catch (Throwable ex) {
						throw new FatalBeanException("Could not copy properties from source to target",ex);
					}
				}
			}
		}
		return result;
	}

	
	/**
	 * 比较两个对象中的指定属性值是否相同，将改变了值的属性以map返回
	 * 
	 * @param source 修改前的对象
	 * @param target 修改后的对象
	 * @param ignoreProperties
	 *            排除比较的属性名
	 * @return Map,返回属性修改明细，没修改的属性不返回，key是属性名称，value是修改说明，如从XX改为AA
	 * @throws BeansException
	 */
	public static Map<String, Object> compareObject(Object source, Object target,
			String[] ignoreProperties) throws BeansException {
		Map<String, Object> map = new HashMap<String, Object>(0);
		if (!source.getClass().isInstance(target)){
			return map;
		}
		Assert.notNull(source, "Source must not be null");
		Assert.notNull(target, "Target must not be null");
		Class<?> actualEditable = target.getClass();
		PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
		List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
		for (PropertyDescriptor targetPd : targetPds) {
			if (targetPd.getWriteMethod() != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
				PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getName());
				if (sourcePd != null && sourcePd.getReadMethod() != null) {
					try {
						Method readMethod = sourcePd.getReadMethod();
						if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
							readMethod.setAccessible(true);
						}
						//修改前的属性值
						Object value = readMethod.invoke(source);
						Method readMethod2 = targetPd.getReadMethod();
						if (!Modifier.isPublic(readMethod2.getDeclaringClass().getModifiers())) {
							readMethod2.setAccessible(true);
						}
						//修改后的属性值
						Object value2 = readMethod2.invoke(target);
						
						if (value == null && value2 == null) {
							continue;
						} else if (value != null && value2 != null) {
							if (value.equals(value2)) {
								continue;
							} else {
								if (value instanceof ArrayList && value2 instanceof ArrayList){
									List list1 = (List) value;
									List list2 = (List) value2;
									map.putAll(comparePropertyOfList(list1, list2, "tag"));
								}else {
									map.put(sourcePd.getName(), value + " <b>修改为</b>  " + value2);
								}
							}
						} else {
							if (value != null){
								map.put(sourcePd.getName(), "<b>已删除值</b>  " + value);
							}else if (value2 != null){
								map.put(sourcePd.getName(), "<b>从空值改为</b>  " + value2);
								
							}
						}
					} catch (Throwable ex) {
						throw new FatalBeanException("Could not copy properties from source to target",ex);
					}
				}
			}
		}
		return map;
	}
	

	
	
	/**
	 * 比较两个对象的指定属性值是否相等，用来联系人标签列表比较
	 * @param sourceList
	 * @param targetList
	 * @param compareProperty
	 * @return 以Map返回，key是属性名称，value是修改说明，如从XX改为AA
	 */
	public static Map<String, Object> comparePropertyOfList(List<?> sourceList, List<?> targetList, String compareProperty){
		Map<String, Object> map = new HashMap<String, Object>(0);
		StringBuffer sourceStr = new StringBuffer();
		StringBuffer targetStr = new StringBuffer();
		if (sourceList.size() == 0 && targetList.size() == 0 || compareProperty == null){
			return map;
		}else {
			if (sourceList.size() == 0){
				targetStr = getvalueOfListProperty(targetList, compareProperty);
				map.put(compareProperty, "空值改为 " + targetStr);
			}else if (targetList.size() == 0){
				sourceStr = getvalueOfListProperty(sourceList, compareProperty);
				map.put(compareProperty, "删除值  " + targetStr);
			}else {
				sourceStr = getvalueOfListProperty(sourceList, compareProperty);
				targetStr = getvalueOfListProperty(targetList, compareProperty);
				if (sourceStr != null && targetStr != null){
					map.put("tagList", sourceStr +" 改为 " + targetStr);
				}
			}
		}
		return map;
	}
	
	
	/**
	 * 将list中对象指定的属性值组合成字符串，以;分隔
	 * @param list
	 * @param pro
	 * @return
	 */
	public static StringBuffer getvalueOfListProperty(List<?> list, String pro){
		if (list == null || list.size() == 0 || pro == null){
			return null;
		}else {
			StringBuffer listValue = new StringBuffer();
			for (int i = 0; i < list.size(); i ++){
				Class<?> clazz = list.get(i).getClass();
				if (!clazz.isInstance(String.class) ){
					PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(clazz);
					for (PropertyDescriptor targetPd : targetPds) {
						if (targetPd.getWriteMethod() != null && (pro == null || (pro.equals(targetPd.getName())))) {
									Method readMethod = targetPd.getReadMethod();
									if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
										readMethod.setAccessible(true);
									}
									try {
										Object value = readMethod.invoke(list.get(i));
										if (value != null){
											listValue.append(value);
											listValue.append("; ");
										}
									} catch (IllegalArgumentException e) {
										e.printStackTrace();
									} catch (IllegalAccessException e) {
										e.printStackTrace();
									} catch (InvocationTargetException e) {
										e.printStackTrace();
									}
							}
						}
				}
			}
			return listValue;
			}
	}
	
	/**
	 * 比较两个集合中的实体中的指定Map建的值是否相等
	 * 
	 * @param source
	 * @param target
	 * @param properties
	 *            要比较的属性名
	 * @return 有不同的值则返回false
	 * @throws BeansException
	 */
	public static boolean comparePropertiesForMapList(List<Map<String, Object>> source, List<Map<String, Object>> target,
			String[] properties) throws BeansException {
		boolean isalter = true;

		Assert.notNull(source, "Source must not be null");
		Assert.notNull(target, "Target must not be null");
		if (source.size() == 0 && target.size() == 0){
			return isalter;
		}else if (source.size() != target.size()){
			isalter = false;
			return isalter;
		}else {
			try {
				for (int i = 0; i < source.size(); i++){
					Map<String, Object> sourceMap = source.get(i);
					Map<String, Object> targetMap = target.get(i);
					for (int j = 0; j < properties.length; j++){
						
						if (properties[j] != null && sourceMap.containsKey(properties[j]) && targetMap.containsKey(properties[j])){
							Object obj1 = sourceMap.get(properties[j]);
							Object obj2 = targetMap.get(properties[j]);
							String smp = obj1 == null ? null : obj1.toString();
							String tmp = obj2 == null ? null : obj2.toString();
							if (StringUtil.isNotBlank(smp) && StringUtil.isNotBlank(tmp)){
								if (StringUtil.compare(sourceMap.get(properties[j]).toString(), targetMap.get(properties[j]).toString())){
									continue;
								}
								isalter = false;
								return isalter;
							}
						}
					}
				}
			} catch (NullPointerException e) {
				e.printStackTrace();
			} 
		}
		return isalter;
	}
	
	
	/**
	 * 比较两个集合中的实体中的指定属性值是否相同，相同则返回true
	 * 
	 * @param source
	 * @param target
	 * @param properties
	 *            要比较的属性名
	 * @return
	 * @throws BeansException
	 */
	public static boolean comparePropertiesForList(List<?> source, List<?> target,
			String[] properties) throws BeansException {
		boolean isalter = true;

		Assert.notNull(source, "Source must not be null");
		Assert.notNull(target, "Target must not be null");
		if (source.size() == 0 && target.size() == 0){
			return isalter;
		}else if (source.size() != target.size()){
			isalter = false;
		}else {
			for (int i = 0; i < source.size(); i++){
				Class<?> actualEditable = target.get(i).getClass();
				PropertyDescriptor[] targetPds = BeanUtils
						.getPropertyDescriptors(actualEditable);
				List<String> compareList = (properties != null) ? Arrays
						.asList(properties) : null;
				for (PropertyDescriptor targetPd : targetPds) {
					if (targetPd.getWriteMethod() != null && (properties == null || compareList.contains(targetPd.getName()))) {
						PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(
								source.get(i).getClass(), targetPd.getName());
						
						if (sourcePd != null && sourcePd.getReadMethod() != null) {
							try {
								Method readMethod = sourcePd.getReadMethod();
								if (!Modifier.isPublic(readMethod.getDeclaringClass()
										.getModifiers())) {
									readMethod.setAccessible(true);
								}
								Object value = readMethod.invoke(source.get(i));
								Method readMethod2 = targetPd.getReadMethod();
								if (!Modifier.isPublic(readMethod2.getDeclaringClass()
										.getModifiers())) {
									readMethod2.setAccessible(true);
								}
								Object value2 = readMethod2.invoke(target.get(i));
								if (value == null && value2 == null) {
									continue;
								} else if (value != null && value2 != null) {
									if (value.equals(value2)) {
										continue;
									} else {
										isalter = false;
										return isalter;
									}
								} else {
									continue;
								}
							} catch (Throwable ex) {
								throw new FatalBeanException(
										"Could not copy properties from source to target",
										ex);
							}
						}
					}
				}
			}
		}
		return isalter;
	}
	
	
	/**
	 * 比较两个集合中的实体中的指定属性值是否相同，相同则返回true
	 * 
	 * @param source
	 * @param target
	 * @return
	 * @throws BeansException
	 */
	public static List<?> comparePropertiesForList(List<?> source, List<?> target) throws BeansException {
		List isalter = new ArrayList();

		Assert.notNull(source, "Source must not be null");
		Assert.notNull(target, "Target must not be null");
		try {
		if (source.size() == 0 && target.size() == 0){
			return isalter;
		}else if (source.size() == 0 || target.size() == 0){
			if (source.size() == 0){
				return isalter;
			}else {
				return source;
			}
		}else if (source.size() > target.size()){
			for (int i = 0; i < source.size(); i++){
				Class<?> actualEditable = target.get(i).getClass();
				PropertyDescriptor[] targetPds = BeanUtils
						.getPropertyDescriptors(actualEditable);
				for (PropertyDescriptor targetPd : targetPds) {
					if (targetPd.getWriteMethod() != null) {
						PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.get(i).getClass(), targetPd.getName());
						if (sourcePd != null && sourcePd.getReadMethod() != null) {
							Method readMethod = sourcePd.getReadMethod();
							if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
								readMethod.setAccessible(true);
							}
							Object value = readMethod.invoke(source.get(i));
							Method readMethod2 = targetPd.getReadMethod();
							if (!Modifier.isPublic(readMethod2.getDeclaringClass().getModifiers())) {
								readMethod2.setAccessible(true);
							}
							Object value2 = readMethod2.invoke(target.get(i));

							if (value == null && value2 == null) {
								continue;
							} else if (value != null && value2 != null) {
								if (value.equals(value2)) {
									continue;
								} else {
									return isalter;
								}
							} else {
								return isalter;
							}
						}
					}
				}
			}
			return isalter;
		}else if (source.size() < target.size()){
			return source;
		}else {//两个集合中都有对象
			for (int i = 0; i < source.size(); i++){
				Class<?> actualEditable = target.get(i).getClass();
				PropertyDescriptor[] targetPds = BeanUtils
						.getPropertyDescriptors(actualEditable);
				for (PropertyDescriptor targetPd : targetPds) {
					if (targetPd.getWriteMethod() != null) {
						PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.get(i).getClass(), targetPd.getName());
						if (sourcePd != null && sourcePd.getReadMethod() != null) {
								Method readMethod = sourcePd.getReadMethod();
								if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
									readMethod.setAccessible(true);
								}
								Object value = readMethod.invoke(source.get(i));
								Method readMethod2 = targetPd.getReadMethod();
								if (!Modifier.isPublic(readMethod2.getDeclaringClass().getModifiers())) {
									readMethod2.setAccessible(true);
								}
								Object value2 = readMethod2.invoke(target.get(i));

								if (value == null && value2 == null) {
									continue;
								} else if (value != null && value2 != null) {
									if (value.equals(value2)) {
										continue;
									} else {
										return isalter;
									}
								} else {
									return isalter;
								}
						}
					}
				}
			}
		}
		} catch (FatalBeanException ex) {
			ex.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return isalter;
	}
	
	
	/**
	 * 比较两个实体的实例同一个属性的值相同点,此方法专用于流程变更业务
	 * 
	 * @param newone
	 * @param oldone
	 * @param property
	 * @return
	 * @throws BeansException
	 */
	public static String compareProperty(Object newone, Object oldone,
			String property) throws BeansException {
		String result = null;

		Assert.notNull(newone, "Source must not be null");
		Assert.notNull(oldone, "Target must not be null");
		Class<?> actualEditable = oldone.getClass();
		PropertyDescriptor[] targetPds = BeanUtils
				.getPropertyDescriptors(actualEditable);
		for (PropertyDescriptor targetPd : targetPds) {
			if (targetPd.getReadMethod() != null && property != null && property.equals(targetPd.getName())) {
				PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(
						newone.getClass(), targetPd.getName());
				if (sourcePd != null && sourcePd.getReadMethod() != null) {
					try {
						Method readMethod = sourcePd.getReadMethod();
						if (!Modifier.isPublic(readMethod.getDeclaringClass()
								.getModifiers())) {
							readMethod.setAccessible(true);
						}
						Object value1 = readMethod.invoke(newone);// 改变后的值
						Method readMethod2 = targetPd.getReadMethod();
						if (!Modifier.isPublic(readMethod2.getDeclaringClass()
								.getModifiers())) {
							readMethod2.setAccessible(true);
						}
						Object value2 = readMethod2.invoke(oldone);// 改变前的值

						if (value1 == null && value2 == null) {
							result = "";
						} else if (value1 != null && value2 != null) {
							if (value1.equals(value2)) {
								result = value2.toString();
							} else {
								result = "<font color='red'>" + value1 + "</font>";
							}
						} else {
							if (value1 != null) {
								result = "<font color='red'>" + value1 + "</font>";
							} else {
								result = "<font color='red'>&nbsp;</font>";
							}
						}
						break;
					} catch (Throwable ex) {
						throw new FatalBeanException("读取属性值错误", ex);
					}
				}
			}
		}
		return result;
	}

	/**
	 * 将对象属性名转换成对应中文显示名
	 * @param pNameMap
	 * @param valueMap
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static String convertPropertyName(Map<String, Object> pNameMap, Map<String, Object> valueMap){
		if (pNameMap == null || valueMap == null || pNameMap.size() == 0 || valueMap.size() == 0){
			return "";
		}
		StringBuffer nameValue = new StringBuffer();
		for (Iterator iterator = valueMap.keySet().iterator(); iterator.hasNext();) {
			String key = (String) iterator.next();
			nameValue.append(pNameMap.get(key) + " : " + valueMap.get(key) + "; ");
		}
		return nameValue.toString();
	}
	
	/**
	 * 将对象属性名转换成对应中文显示名,并以map返回
	 * @param pNameMap
	 * @param valueMap
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static Map<String, Object> convertPropertyNameMap(Map<String, Object> pNameMap, Map<String, Object> valueMap){
		Map<String, Object> newMap = new HashMap<String, Object>(0);
		if (pNameMap == null || valueMap == null || pNameMap.size() == 0 || valueMap.size() == 0){
			return newMap;
		}
		for (Iterator iterator = valueMap.keySet().iterator(); iterator.hasNext();) {
			String key = (String) iterator.next();
			newMap.put(pNameMap.get(key).toString(), valueMap.get(key));
		}
		return newMap;
	}
	
	/**
	 * 将对象属性名转换成对应中文显示名
	 * @param pNameMap 属性名map
	 * @param valueMap 值map
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static String convertListPropertyName(Map<String, Object> pNameMap, List<Map<String, Object>> valueMap){
		if (pNameMap == null || valueMap == null || pNameMap.size() == 0 || valueMap.size() == 0){
			return null;
		}
		StringBuffer nameValue = new StringBuffer();
		for (int i = 0 ; i < valueMap.size(); i ++){
			Map<String, Object> vmap = valueMap.get(i);
			for (Iterator iterator = vmap.keySet().iterator(); iterator.hasNext();) {
				String key = (String) iterator.next();
				nameValue.append(pNameMap.get(key) + " : " + vmap.get(key) + "; ");
			}
		}
		return nameValue.toString();
	}
	
	
	public static void main(String[] args) {



	}

}
